package com.gcloud.mesh.alert.redis;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.gcloud.mesh.alert.consts.RedisKeyConsts;
import com.gcloud.mesh.header.exception.BaseException;
import com.gcloud.mesh.header.vo.alert.HistoryVo;

@Service("AlarmRedis")
public class AlarmRedis {

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	private Long sessionTimeout = 3000l;

	// 告警规则(meter)_资源id {告警等级、告警时间、告警次数、告警通知的方式、告警meter}
	// 恢复则删除 告警记录
	// 告警过期时间为是通道沉默时间内
	// 告警恢复通知是告警在通道沉默时间内还是一天？

	private HistoryVo getByKey(String ruleId, HistoryVo alarmHistoryVo, String instance, Long expireDate)
			throws BaseException {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		Set<String> keys = redisTemplate.keys(key);

		if (keys != null && keys.size() > 0) {
			for (String k : keys) {
				BoundValueOperations<String, Object> valueOperations = redisTemplate.boundValueOps(k);
				HistoryVo res = (HistoryVo) valueOperations.get();
				if (res != null) {
					if (expireDate != null) {
						// 更新session
						updateTimeout(k, expireDate);
					}
					return res;
				} else {
					return null;
				}
			}
		}
		return null;
	}

	public HistoryVo get(String ruleId, String meter, String resourceId, String host, String platformType,
			String regionId, String instance, Long expireDate) throws BaseException {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_RULE_ID_METER_OBJECT_ID, ruleId, meter,
				resourceId, host, instance);
		if (platformType != null && regionId != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_RULE_ID_METER_OBJECT_ID,
					platformType, regionId, ruleId, meter, resourceId, host, instance);
		}
		Set<String> keys = redisTemplate.keys(key);

		if (keys != null && keys.size() > 0) {
			for (String k : keys) {
				BoundValueOperations<String, Object> valueOperations = redisTemplate.boundValueOps(k);
				HistoryVo res = (HistoryVo) valueOperations.get();
				if (res != null) {
					if (expireDate != null) {
						// 更新session
						updateTimeout(k, expireDate);
					}
					return res;
				} else {
					return null;
				}
			}
		}
		return null;
	}

	public void updateTimeout(String key, Long expireDate) throws BaseException {
		redisTemplate.expire(key, expireDate, TimeUnit.SECONDS);
	}

	/**
	 * 将ruleId和alarmHistoryVo放入redis中 带有生存时间
	 * 
	 * @param ruleId
	 * @param alarmHistoryVo
	 * @param expireDate
	 * 
	 * @throws GCloudException
	 */
	public void set(String ruleId, HistoryVo alarmHistoryVo, String instance, Long expireDate) throws BaseException {
		// 告警规则(meter)_资源id {告警等级、告警时间、告警次数、告警通知的方式、告警meter}
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		BoundValueOperations<String, Object> valueOperations = redisTemplate.boundValueOps(key);
		valueOperations.set(alarmHistoryVo);

		redisTemplate.expire(key, expireDate, TimeUnit.SECONDS);
	}

	/**
	 * 将ruleId和alarmHistoryVo更新到redis中 带有生存时间
	 * 
	 * @param ruleId
	 * @param alarmHistoryVo
	 * 
	 * @throws GCloudException
	 */
	public void update(String ruleId, HistoryVo alarmHistoryVo, String instance, Long expireDate) throws BaseException {
		// 告警规则(meter)_资源id {告警等级、告警时间、告警次数、告警通知的方式、告警meter}
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		BoundValueOperations<String, Object> valueOperations = redisTemplate.boundValueOps(key);
		valueOperations.set(alarmHistoryVo);
		if (redisTemplate.getExpire(key, TimeUnit.SECONDS) <= 0) {
			redisTemplate.expire(key, expireDate, TimeUnit.SECONDS);
		}
		;
	}

	/**
	 * 
	 * @Title: remove
	 * @Description: TODO
	 * 
	 * @param ruleId
	 * @throws GCloudException
	 */
	public void remove(String ruleId, HistoryVo alarmHistoryVo, String instance, Long expireDate) throws BaseException {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		Set<String> keys = redisTemplate.keys(key);
		if (keys != null && keys.size() > 0) {
			for (String k : keys) {
				redisTemplate.delete(k);
			}
		}
	}

	/**
	 * 将告警计数放入redis中，不带生存时间
	 * 
	 * @param ruleId
	 * @param alarmCount
	 * 
	 * @throws GCloudException
	 */
	public void set(String ruleId, Integer alarmCount, HistoryVo alarmHistoryVo, String instance) throws BaseException {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_COUNT_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_COUNT_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		BoundValueOperations<String, Object> valueOperations = redisTemplate.boundValueOps(key);
		valueOperations.set(alarmCount);
	}

	public Integer get(String ruleId, HistoryVo alarmHistoryVo, String instance) {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_COUNT_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_COUNT_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		return (Integer) redisTemplate.opsForValue().get(key);
	}

	public void remove(String ruleId, HistoryVo alarmHistoryVo, String instance) {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_COUNT_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_COUNT_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		redisTemplate.delete(key);
	}

	// 推送告警事件
	public void set(String ruleId, HistoryVo alarmHistoryVo, String instance, Integer isSendToUrl) {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.AlARM_PUSH_RULE_ID_METER_OBJECT_ID, ruleId,
				alarmHistoryVo.getMeter(), alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		// 多云改造
		if (alarmHistoryVo.getPlatformType() != null && alarmHistoryVo.getRegionId() != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_PUSH_RULE_ID_METER_OBJECT_ID,
					alarmHistoryVo.getPlatformType(), alarmHistoryVo.getRegionId(), ruleId, alarmHistoryVo.getMeter(),
					alarmHistoryVo.getResourceId(), alarmHistoryVo.getHost(), instance);
		}
		BoundValueOperations<String, Object> valueOperations = redisTemplate.boundValueOps(key);
		valueOperations.set(isSendToUrl);
	}

	public Integer get(String ruleId, String meter, String resourceId, String host, String platformType,
			String regionId, String instance) {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.AlARM_PUSH_RULE_ID_METER_OBJECT_ID, ruleId, meter,
				resourceId, host, instance);
		// 多云改造
		if (platformType != null && regionId != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_PUSH_RULE_ID_METER_OBJECT_ID,
					platformType, regionId, ruleId, meter, resourceId, host, instance);
		}
		return (Integer) redisTemplate.opsForValue().get(key);
	}

	public void remove(String ruleId, String meter, String resourceId, String host, String platformType,
			String regionId, String instance) {
		String key = MessageFormat.format(RedisKeyConsts.RedisKey.AlARM_PUSH_RULE_ID_METER_OBJECT_ID, ruleId, meter,
				resourceId, host, instance);
		// 多云改造
		if (platformType != null && regionId != null) {
			key = MessageFormat.format(RedisKeyConsts.RedisKey.ALARM_PLATFORM_REGION_PUSH_RULE_ID_METER_OBJECT_ID,
					platformType, regionId, ruleId, meter, resourceId, host, instance);
		}
		redisTemplate.delete(key);
	}

	public List<String> getKeys(String meter) {
		String allKey = MessageFormat.format(RedisKeyConsts.RedisKey.MONITOR_DATA, meter, "*");

		List<String> res = new ArrayList<String>();
		Set<String> keys = redisTemplate.keys(allKey);

		for (String key : keys) {
			res.add(key.replaceAll(MessageFormat.format(RedisKeyConsts.RedisKey.MONITOR_DATA, meter, ""), "").trim());
		}
		return res;
	}
}
